package com.alameda.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 对象工具类
 *
 * @author Lv
 * @date 2024/2/19
 */
public class ObjectUtils {
    /**
     * 对象数据模型转换
     *
     * @param sourceObject 源对象
     * @param targetClass  目标对象
     * @param <S>          目标对象字节码
     * @param <T>          目标对象泛型
     * @return
     */
    public static <S, T> T convert(S sourceObject, Class<T> targetClass) {
        String jsonString = JSONObject.toJSONString(sourceObject);
        return JSONObject.parseObject(jsonString, targetClass);
    }

    /**
     * 单列集合数据模型转换
     *
     * @param sourceObjectList 源集合
     * @param targetClass      目标对象字节码
     * @param <S>              源对象泛型
     * @param <T>              目标对象泛型
     * @return
     */
    public static <S, T> List<T> convertList(Collection<S> sourceObjectList, Class<T> targetClass) {
        if (sourceObjectList == null) {
            List<T> tList = null;
            try {
                tList = Collections.singletonList(targetClass.newInstance());
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
            return tList;
        }
        return sourceObjectList.stream()
                .map(item -> convert(item, targetClass))
                .collect(Collectors.toList());
    }

    /**
     * 分页对象数据模型转换
     *
     * @param sourcePageData 源分页对象
     * @param targetClass    目标对象字节码
     * @param <S>            源对象泛型
     * @param <T>            目标对象泛型
     * @return
     */
    public static <S, T> IPage<T> convertPageData(IPage<S> sourcePageData, Class<T> targetClass) {
        List<S> sourcePageDataRecords = sourcePageData.getRecords();
        List<T> targetList = ObjectUtils.convertList(sourcePageDataRecords, targetClass);
        IPage<T> pageVO = new Page<>();
        pageVO.setRecords(targetList);
        pageVO.setCurrent(sourcePageData.getCurrent());
        pageVO.setSize(sourcePageData.getSize());
        pageVO.setPages(sourcePageData.getPages());
        pageVO.setTotal(sourcePageData.getTotal());
        return pageVO;
    }

    /**
     * 为指定对象(或者集合列表)设置某个字段值
     *
     * @param obj        指定对象，必填
     * @param fieldName  字段名，必填
     * @param fieldValue 字段值，允许为null
     */
    @SuppressWarnings("all")
    public static void setFieldValueByName(Object obj, String fieldName, Object fieldValue) {
        if (obj == null) {
            return;
        }

        if (PubUtils.isEmpty(fieldName)) {
            return;
        }

        if (obj instanceof Collection) {
            Collection collection = (Collection) obj;
            for (Object o : collection) {
                setFieldValueByNameForObject(o, fieldName, fieldValue);
            }
        } else {
            setFieldValueByNameForObject(obj, fieldName, fieldValue);
        }
    }

    /**
     * 为指定对象设置某个字段值
     *
     * @param obj        指定对象，必填
     * @param fieldName  字段名，必填
     * @param fieldValue 字段值，允许为null
     */
    private static void setFieldValueByNameForObject(Object obj, String fieldName, Object fieldValue) {
        if (obj == null) {
            return;
        }

        if (PubUtils.isEmpty(fieldName)) {
            return;
        }

        try {
            Field declaredField = obj.getClass().getDeclaredField(fieldName);
            declaredField.setAccessible(true);
            declaredField.set(obj, fieldValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
